home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.mactech.com 2010
/
ftp.mactech.com.tar
/
ftp.mactech.com
/
src
/
mactech
/
volume14_1998
/
14.12.sit
/
14.12
/
Poor Man's Bryce 3.0
/
Image.c
next >
Wrap
Text File
|
1998-06-24
|
6KB
|
197 lines
// Image.c
// ©1998 Kas Thomas. Portions © Xplain Corp.
// Use at your own risk.
//
// Purpose of module:
// QuickTime routines for image handling.
//
// NOTE:
// You will need to soft-link to the latest QuickTimeLib module
// in order to avoid link-time errors with this set of routines.
// Get QuickTime 3.0!
#include <ImageCompression.h>
#include <math.h>
#include <QDOffscreen.h>
#include "Image.h"
#define HALVE_RECT(r) { r.right /= 2; r.bottom /= 2; }
#define MULTIPLY_RECT(r,f) { r.left *= f; r.right *=f; r.bottom *=f; r.top *=f; }
#define RECT_AREA(r) ( (r.right-r.left)*(r.bottom-r.top) )
#define MARGIN 50
// ------------------------- DrawMyGraphicsFile() ------------------------
// Using QuickTime's ImageCompression.h and Component.h routines, try to
// open whatever image file the user has specified and display the image
// in an appropriately sized window.
void DrawMyGraphicsFile(const FSSpec *fss)
{
GraphicsImportComponent gi;
Rect naturalBounds;
long err;
extern WindowPtr gImageWindow;
extern void TellUser(Str255 errmsg, OSErr errcode );
err = GetGraphicsImporterForFile(fss, &gi); // see if QT can handle the file
if (err) {
TellUser("\pSorry, can't open this file.", err);
return;
}
// get native dimensions of image
err = GraphicsImportGetNaturalBounds (gi,&naturalBounds);
if (err)
SetRect(&naturalBounds, MARGIN,MARGIN,400,400);
// if too big to fit screen, downsize
while (naturalBounds.right + MARGIN > (**GetMainDevice()).gdRect.right)
HALVE_RECT(naturalBounds);
while (naturalBounds.bottom + MARGIN > (**GetMainDevice()).gdRect.bottom)
HALVE_RECT(naturalBounds);
OffsetRect(&naturalBounds,MARGIN,MARGIN); // allow some breathing room
gImageWindow = NewCWindow(nil, // create proper size window
&naturalBounds,
fss->name,
true,
noGrowDocProc,
(WindowPtr)-1,
true,
0) ;
GraphicsImportSetBoundsRect(gi, &naturalBounds); // tell QT the destination rect bounds
err=GraphicsImportDraw(gi); // tell QT to draw the image into the rect
CloseComponent(gi); // tell QT we're done with the importer
}
// ------------------------- GetMyGraphicsFile() ------------------------
// Prompt user for a graphics file.
void GetMyGraphicsFile(StandardFileReply *reply)
{
OSType imageFormats[] = { 'TIFF',
'GIFf',
'gif ',
'JPEG',
'PICT',
'8BPS' } ;
StandardGetFilePreview(nil, 6, imageFormats, reply);
}
// ------------------------- GetMyGraphicsFilePixmap() ------------------------
PixMapHandle GetMyGraphicsFilePixmap(const FSSpec *fss, long maxPixelLimit)
{
PixMapHandle offPix;
long err, pixelCount;
double shrinkFactor;
Rect imageBounds;
GraphicsImportComponent gi;
CGrafPtr curPort,newPort;
GDHandle curDevice,newDevice;
extern GWorldPtr gOffScreenGWorld;
GetGWorld( &curPort, &curDevice ); // get current state
err = GetGraphicsImporterForFile(fss, &gi); // see if QT can handle the file
if (err) {
TellUser("\pSorry, can't open this file.", err);
return nil;
}
// get native dimensions of image
err = GraphicsImportGetNaturalBounds (gi,&imageBounds);
if (err) {
TellUser("\pCan't get image bounds.", err);
return nil;
}
// how many pixels?
pixelCount = (imageBounds.right - imageBounds.left) *
(imageBounds.bottom - imageBounds.top);
if (pixelCount > maxPixelLimit) { // are we over the limit?
shrinkFactor = (double)maxPixelLimit/pixelCount; // find pixel reduction factor
shrinkFactor = sqrt( shrinkFactor ); // get square root
MULTIPLY_RECT(imageBounds,shrinkFactor); // subsample the dest rect down
}
// NOTE: We preflight our memory situation now. Important to do this, because
// NewGWorld (our next call, below) doesn't fail gracefully if memory is low.
if (TempFreeMem() < RECT_AREA(imageBounds) + 1000) {
CloseComponent(gi);
TellUser("\pNot enough memory to do this right now.", 0);
return nil;
}
// grab an offscreen draw area
err = NewGWorld( &gOffScreenGWorld, 32, &imageBounds, nil, curDevice, useTempMem);
if (err) {
TellUser("\pCan't get offscreen buffer.", err);
return nil;
}
offPix = GetGWorldPixMap( gOffScreenGWorld ); // grab the pixmap
LockPixels(offPix); // lock it down
SetGWorld( gOffScreenGWorld, nil ); // use the GWorld to draw into
GraphicsImportSetBoundsRect(gi, &imageBounds); // set bounds
GetGWorld( &newPort, &newDevice ); // get port/device of GWorld
GraphicsImportSetGWorld( gi, newPort, newDevice ); // inform QT of the new world order
GraphicsImportDraw(gi); // draw into back buffer
CloseComponent(gi); // close the QT component
SetGWorld( curPort, curDevice ); // restore the old port & device
return offPix; // return the pixmap handle
}
// -------------------- CreateWinPict() ---------------
// Take a snapshot of a given window.
PicHandle CreateWinPict( WindowPtr pictWindow )
{
PicHandle hPict;
SetPort(pictWindow); // not much good if we don't do this!
ClipRect( &pictWindow->portRect );
hPict = OpenPicture( &pictWindow->portRect ); // start recording
BlankIt(); // normalize colors to prevent artifacts
CopyBits( &pictWindow->portBits, &pictWindow->portBits,
&pictWindow->portRect, &pictWindow->portRect, srcCopy, 0L );
ClosePicture(); // stop recording
return( hPict );
}
/* --------------------- BlankIt() ------------------- */
// Call this before any call to CopyBits(). Or else risk
// unwanted colorizing artifacts.
void BlankIt(void)
{
RGBColor blackRGB = {0, 0, 0};
RGBColor whiteRGB = {65535, 65535, 65535};
RGBForeColor(&blackRGB);
RGBBackColor(&whiteRGB);
}